package handler;

import http.MyHttpRequest;
import http.MyHttpResponse;
import http.four4xx.AuthenticationRequired;

import java.io.IOException;
import java.net.Socket;
import java.util.*;

/**
 * @author Karl
 * @Date 2023/1/11 - 19:28
 */
public class AuthenticateHandler implements Handler {

    /**
     * 记录了需要验证权限登录的网站，以及对应账号密码的
     */


    public static Set<String> authenticateSet = null;

    public static MyHttpResponse defaultResponse = new AuthenticationRequired();

    //账号密码，转换成BASE64后用:连接的字符串
    public static Set<String> users;

    public AuthenticateHandler() {
        users = new HashSet<>();
        authenticateSet = new HashSet<>();
        try {
            ResourceBundle bundle = ResourceBundle.getBundle("users");
            ResourceBundle web = ResourceBundle.getBundle("authenticate");

            Enumeration<String> keys = bundle.getKeys();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();
                //通过username和password进行base64加密得到一个串
                // 然后和请求里面传过来的Proxy-Authorization比较，一致的话就认证成功。
                users.add(Base64.getEncoder().encodeToString((key + ":" + bundle.getString(key)).getBytes()));
            }

            keys = web.getKeys();
            while (keys.hasMoreElements()) {
                authenticateSet.add(keys.nextElement());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean handler(MyHttpRequest request, Socket from, Socket to) {
        try {
            defaultResponse.sendMessage(from.getOutputStream());
        } catch (IOException e) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isSupport(MyHttpRequest request, Socket remote) {
        //判断是否需要身份认证
        if(authenticateSet.contains(request.getHost())){
            String header = null;
            //是否通过身份认证
            if((header = request.getRequestHeader("Proxy-Authorization"))!=null){
                String[] split = header.trim().split(" ");
                return split.length >= 3 && !users.contains(split[2]);
            }
            return true;
        }
        return false;
    }
}
